package cn.wizzer.app.web.commons.utils;

import cn.wizzer.app.match.modules.models.constant.RedisKey;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.constant.ChatConstant;
import cn.wizzer.app.user.modules.models.vo.LiveInfo;
import cn.wizzer.app.web.commons.ext.websocket.main.base.TextWebSocketFrameHandler;
import cn.wizzer.app.web.commons.ext.websocket.main.result.ChatResult;
import cn.wizzer.framework.base.exceptions.BizException;
import cn.wizzer.framework.util.JSONUtil;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.nutz.lang.Strings;

import java.util.Map;

import static cn.wizzer.app.user.modules.models.constant.ChatConstant.*;

public class NettyMsgUtil {
    /**
     * 加入房间
     *
     * @param incoming
     * @param user
     * @param newRoomName
     * @return
     */
    public static boolean joinRoom(Channel incoming, User user, String newRoomName) {
        if (!newRoomName.equals(DEFAULT) && newRoomName.equals(RedisUtil.hget(User.class, ChatConstant.CHAT_USER, incoming.id().toString()).getRoomId())) {
            send(incoming, ChatResult.MessageTypeEnum.SYSTEM, ChatResult.ActionEnum.REMAND, null, "重复加入房间");
            return false;
        }
        ChannelGroup channels = getLiveRoomChannels(newRoomName, incoming);
        if (channels == null) {
            return false;
        }
        // 房间中添加用户信息
        RedisUtil.hset(CHAT_ROOM + newRoomName, incoming.id().toString(), user.getId());
        //更新用户所在房间信息
        user.setRoomId(newRoomName);
        RedisUtil.hset(CHAT_USER, incoming.id().toString(), user);
        channels.add(incoming);
        //直播间人数变动
        if (!DEFAULT.equals(newRoomName)) {
            LiveInfo liveInfo = RedisUtil.hget(LiveInfo.class, RedisKey.KEY_LIVE, newRoomName);
            liveInfo.setUserCount((long) channels.size());
            RedisUtil.hset(RedisKey.KEY_LIVE, newRoomName, liveInfo.toString());
        }
        // 非默认房间再行通知
        if (!DEFAULT.equals(newRoomName)) {
            for (Channel channel : channels) {
                send(channel, ChatResult.MessageTypeEnum.ACTION, ChatResult.ActionEnum.JOIN, user, null);
            }
        }
        return true;
    }

    /**
     * 离开房间
     *
     * @param incoming
     */
    public static Boolean leaveRoom(Channel incoming, String originRoom) {

        if (!DEFAULT.equals(originRoom)) {
            ChannelGroup channels = getLiveRoomChannels(originRoom, incoming);
            String channelId = incoming.id().toString();
            User user = RedisUtil.hget(User.class, ChatConstant.CHAT_USER, channelId);
            user.setRoomId(DEFAULT);
            RedisUtil.hset(CHAT_USER, channelId, user);
            //region 直播间人数变动
            channels.remove(incoming);
            LiveInfo liveInfo = RedisUtil.hget(LiveInfo.class, RedisKey.KEY_LIVE, originRoom);
            liveInfo.setUserCount((long) channels.size());
            RedisUtil.hset(RedisKey.KEY_LIVE, originRoom, liveInfo.toString());
            RedisUtil.hdel(CHAT_ROOM + originRoom, channelId);
            //endregion

            for (Channel channel : channels) {
                send(channel, ChatResult.MessageTypeEnum.ACTION, ChatResult.ActionEnum.LEAVE, user, null);
            }
        }

        return true;
    }

    public static ChannelGroup getLiveRoomChannels(String roomId, Channel incoming) {
        ChannelGroup channels = TextWebSocketFrameHandler.channelGroupMap.get(roomId);
        if (null == channels) {
            if (Strings.isNotBlank(RedisUtil.hget(RedisKey.KEY_LIVE, roomId))) {
                return TextWebSocketFrameHandler.createChannelGroup(roomId);
            }
            send(incoming, ChatResult.MessageTypeEnum.SYSTEM, ChatResult.ActionEnum.REMAND, null, "该聊天室不存在");
        }
        return channels;
    }


    public static void sendGiftMessage(String liveNo, String userId, String giftId, int num, String giftName, String coverPic) {
        try {
            String cKey = "";
            for (Map.Entry<String, String> entry : RedisUtil.hgetAll(CHAT_ROOM + liveNo).entrySet()) {
                if (entry.getValue().equals(userId)) {
                    cKey = entry.getKey();
                    break;
                }
            }
            ;
            User user = RedisUtil.hget(User.class, CHAT_USER, cKey);
            ChannelGroup channels = TextWebSocketFrameHandler.channelGroupMap.get(liveNo);
            String jsonString = JSONUtil.createJSONString(
                    "giftId", giftId,
                    "num", num + "",
                    "giftName", giftName,
                    "coverPic", coverPic
            );
            if (channels != null) {
                send(channels, ChatResult.MessageTypeEnum.ACTION, ChatResult.ActionEnum.SEND_GIFT, user, jsonString);
            }
        } catch (BizException be) {
            throw be;
        }
    }
    /**
     * 发送消息
     *
     * @param channel
     * @param type
     * @param action
     * @param user
     * @param content
     */
    public static void send(Channel channel, ChatResult.MessageTypeEnum type, ChatResult.ActionEnum action, User user, String content) {
        try {
            if (type == ChatResult.MessageTypeEnum.ACTION) {
                channel.writeAndFlush(new TextWebSocketFrame(JSONUtil.createJSONString(ChatConstant.PROP_CHAT_USER, JSONUtil.toJSONString(user), ChatConstant.ACTION, action.NAME, ChatConstant.TYPE, type.NAME,ChatConstant.CONTENT, content)));
            } else if (type == ChatResult.MessageTypeEnum.SYSTEM) {
                channel.writeAndFlush(new TextWebSocketFrame(JSONUtil.createJSONString(ChatConstant.CONTENT, content, ChatConstant.ACTION, action.NAME, ChatConstant.TYPE, type.NAME)));
            } else {
                channel.writeAndFlush(new TextWebSocketFrame(JSONUtil.createJSONString(ChatConstant.CONTENT, content, ChatConstant.SENDER, JSONUtil.toJSONString(user), ChatConstant.ACTION, action.NAME, ChatConstant.TYPE, type.NAME)));
            }

        }catch (Exception e){

        }
    }
    public static void send(ChannelGroup channels, ChatResult.MessageTypeEnum type, ChatResult.ActionEnum action, User user, String content) {
        try {
            if (type == ChatResult.MessageTypeEnum.ACTION) {
                channels.writeAndFlush(new TextWebSocketFrame(JSONUtil.createJSONString(ChatConstant.PROP_CHAT_USER, JSONUtil.toJSONString(user), ChatConstant.ACTION, action.NAME, ChatConstant.TYPE, type.NAME,ChatConstant.CONTENT, content)));
            } else if (type == ChatResult.MessageTypeEnum.SYSTEM) {
                channels.writeAndFlush(new TextWebSocketFrame(JSONUtil.createJSONString(ChatConstant.CONTENT, content, ChatConstant.ACTION, action.NAME, ChatConstant.TYPE, type.NAME)));
            } else {
                channels.writeAndFlush(new TextWebSocketFrame(JSONUtil.createJSONString(ChatConstant.CONTENT, content, ChatConstant.SENDER, JSONUtil.toJSONString(user), ChatConstant.ACTION, action.NAME, ChatConstant.TYPE, type.NAME)));
            }

        }catch (Exception e){

        }
    }

}
